home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 April: Mac OS SDK / Dev.CD Apr 00 SDK1.toast / Development Kits / Mac OS / Navigation Services SDK / Examples / StExample / StNavServices.cp < prev    next >
Encoding:
Text File  |  1999-06-16  |  7.3 KB  |  289 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        StNavServices.cp
  3.  
  4.     Copyright:    © 1998 by Apple Computer, Inc., all rights reserved.
  5.  
  6. */
  7.  
  8. //    Stack Based classes for Navigation Services calls - NavGetFile, NavPutFile
  9.  
  10. //    
  11. //    You may incorporate this sample code into your applications
  12. //    without restriction. This sample code has been provided "AS
  13. //    IS" and the responsibility for its operation is 100% yours.
  14. //    You are not permitted to redistribute the source as "Apple
  15. //    sample code" after having made changes. If you're going to
  16. //    re-distribute the source, we require that you make it clear
  17. //    in the source that the code was descended from Apple sample
  18. //    code, but that you've made changes.
  19. //    
  20.  
  21. #include <StNavServices.h>
  22.  
  23. #ifndef _H_UAppleEventsMgr
  24. #include <UAppleEventsMgr.h>
  25. #endif
  26.  
  27. #ifndef _H_UMemoryMgr
  28. #include <UMemoryMgr.h>
  29. #endif
  30.  
  31.  
  32. StNavGetFile::StNavGetFile ( OSErr *result,
  33.                                 void                *specs,
  34.                                 long                *numspecs,
  35.                                 StNavGetFileOpenEventUPP openProc,
  36.                                 NavReplyRecord        *reply,
  37.                                 Boolean                getOneFile,
  38.                                 Boolean                showAllReadableFiles,
  39.                                 NavEventUPP         eventProc,
  40.                                 NavPreviewUPP         previewProc,
  41.                                 NavObjectFilterUPP    filterProc,
  42.                                 NavTypeListHandle    typeList,
  43.                                 NavCallBackUserData    eventProcUD ) :
  44.     fTheirSpecs(nil),
  45.     fTheirEventUPP(eventProc),    
  46.     fTheirEventUD(eventProcUD)            
  47. {
  48.     if ( (*result = Init ( )) != noErr )
  49.         return;
  50.     //    do some parameter checking
  51.     *result = paramErr;
  52.     if ( specs == nil && reply == nil && openProc == nil )
  53.         return;    //    gotta have one of these
  54.     
  55.     fReply.data.Adopt ( new NavReplyRecord );
  56.  
  57. //    use default options         
  58.     NavGetDefaultDialogOptions ( &fdialogOptions );
  59.  
  60. //    only a single file opened    
  61.     if ( getOneFile )
  62.         fdialogOptions.dialogOptionFlags -= kNavAllowMultipleFiles;    //    only a single file
  63.  
  64. //    show all readables
  65.     if ( showAllReadableFiles )
  66.         fdialogOptions.dialogOptionFlags += kNavSelectAllReadableItem;
  67.         
  68. //    try to use file-based open resource for translation information if none given
  69.     NavTypeListHandle types = typeList;
  70.     if ( types == nil )
  71.          types = (NavTypeListHandle)::Get1Resource ( 'open', 128 );    //    try caller's open info
  72.  
  73. //    go do it
  74.     *result = NavGetFile ( nil, fReply.data.Get(), &fdialogOptions, 
  75.                             fTheirEventUPP, previewProc, filterProc, 
  76.                             types, fTheirEventUD );
  77.  
  78.     if ( *result != noErr )
  79.         return;
  80.  
  81.     long theCount;
  82.     *result = AECountItems ( &fReply.data->selection, &theCount );
  83.     if ( *result != noErr )
  84.         return;
  85.     
  86.     FSSpecArrayPtr theirSpecs = (FSSpecArrayPtr) specs;
  87.  
  88. //    see if caller wanted an array of FSSpecs returned
  89.     if ( specs != nil && !getOneFile )
  90.     {
  91.         theirSpecs = (FSSpecArrayPtr) NewPtrClear ( sizeof ( FSSpec ) * theCount );
  92.         if ( (*result = MemError()) != noErr )
  93.             return;
  94.         *(void**)specs = theirSpecs;
  95.         fTheirSpecs = theirSpecs;
  96.     }
  97.  
  98. //    return count information    
  99.     if ( numspecs != nil )
  100.         *numspecs = theCount;
  101.  
  102. //    fill in reply structs, and make any open callbacks        
  103.     for ( int i = 0; i < theCount; i++ )
  104.     {
  105.         StAEDescriptor desc;    
  106.         *result = AEGetNthDesc( &fReply.data->selection, i+1, typeWildCard, nil, desc );
  107.         if ( *result != noErr )
  108.             return;
  109.         FSSpec theSpec;
  110.         try
  111.         {
  112.             StNavGetFile::GetFSSpecFromAEDesc ( desc, theSpec );    //    put reply in FSSpec
  113.         }
  114.         catch ( OSErr err )
  115.         {
  116.             *result = err;
  117.             return;
  118.         }
  119.         
  120.         if ( specs != nil )
  121.             *theirSpecs++ = theSpec;    // copy spec to user's array
  122.             
  123.         if ( openProc != nil )
  124.             CallUniversalProc ( openProc, StNavGetFileOpenProcInfo, &theSpec );
  125.     }
  126.  
  127. //    SUCCESS
  128. //        if user supplies the reply, copy reply data
  129.     if ( reply != nil )
  130.     {
  131.         *reply = *fReply.data.Get();            //    copy reply to user's reply
  132.         delete fReply.data.Release();            //    user must call NavDisposeReply        
  133.     }
  134. }
  135.  
  136. StNavGetFile::~StNavGetFile ( )
  137. {
  138. //    if caller wanted an FSSpecArray, clean up
  139.     if ( fTheirSpecs != nil )
  140.         DisposePtr ( (Ptr)fTheirSpecs );
  141. }
  142.  
  143.  
  144. StNavPutFile::StNavPutFile (     OSErr                *result,
  145.                                 OSType                 fileType,
  146.                                 OSType                 fileCreator,
  147.                                 FSSpecPtr            spec,
  148.                                 NavReplyRecord        *reply,
  149.                                 NavEventUPP         eventProc,
  150.                                 NavCallBackUserData eventProcUD ) :
  151.     fresult(result),
  152.     fTheirEventUPP(eventProc),    
  153.     fTheirEventUD(eventProcUD)
  154. {
  155.     
  156.     if ( (*result = StNavGetFile::Init ( )) != noErr )
  157.         return;
  158.     //    do some parameter checking
  159.     *result = paramErr;
  160.     if ( spec == nil && reply == nil )
  161.         return;    //    gotta have one of these
  162.  
  163.     fReply.data.Adopt ( new NavReplyRecord );
  164.  
  165.     NavGetDefaultDialogOptions ( &fdialogOptions );
  166.  
  167.     *result = NavPutFile ( nil, fReply.data.Get(), &fdialogOptions,
  168.                             fTheirEventUPP, fileType, fileCreator,
  169.                             fTheirEventUD );
  170.     if ( *result != noErr )
  171.         return;
  172.     
  173.     if ( spec != nil )
  174.     {
  175.         StAEDescriptor desc;    
  176.         *result = AEGetNthDesc( &fReply.data->selection, 1, typeWildCard, nil, desc );
  177.         if ( *result != noErr )
  178.             return;
  179.         FSSpec theSpec;
  180.         try
  181.         {
  182.             StNavGetFile::GetFSSpecFromAEDesc ( desc, theSpec );    //    put reply in FSSpec
  183.         }
  184.         catch ( OSErr err )
  185.         {
  186.             *result = err;
  187.             return;
  188.         }
  189.         *spec = theSpec;
  190.     }
  191.     
  192.     if ( reply != nil )
  193.         *reply = *fReply.data.Get();        //    copy reply to user's reply        
  194.     
  195. }
  196.     
  197. StNavPutFile::~StNavPutFile ( )
  198. {
  199.     if ( *fresult == noErr )
  200.         *fresult = NavCompleteSave ( fReply.data.Get(), kNavTranslateInPlace );
  201. }                            
  202.  
  203. OSType StNavGetFile::GetApplSignature ( )
  204. {
  205.     ProcessSerialNumber    PSN;
  206.     ProcessInfoRec        info;
  207.     Str31                processName;
  208.     FSSpec                FileSpec;
  209.     info.processInfoLength = sizeof ( ProcessInfoRec );                         
  210.     info.processName = processName;
  211.     info.processAppSpec = &FileSpec;
  212.     OSErr err = GetCurrentProcess(&PSN);
  213.     GetProcessInformation(&PSN, &info);
  214.     return info.processSignature;
  215. }
  216.  
  217. NavTypeListHandle StNavGetFile::MakeTypeList ( OSType applSignature, int numTypes, OSType *types )
  218. {
  219.     NavTypeListHandle h = (NavTypeListHandle) NewHandleClear ( sizeof (NavTypeList) + 
  220.                                                                 (sizeof (OSType) * (numTypes-1)) );
  221.     if ( h != nil )
  222.     {
  223.         (*h)->componentSignature = (applSignature == 0L) ? 
  224.                                     StNavGetFile::GetApplSignature ( ) : applSignature;
  225.         (*h)->reserved = 0;
  226.         (*h)->osTypeCount = numTypes;
  227.         for ( int i = 0; i < numTypes; i++ )
  228.         {
  229.             (*h)->osType[i] = types[i];
  230.         }
  231.     }
  232.     return h;
  233.                                                                     
  234. }
  235.  
  236. NavTypeListHandle StNavGetFile::MakeTypeList ( OSType applSignature, int numTypes, ... )
  237. {
  238.     va_list        argptrs;        
  239.     va_start ( argptrs, numTypes );
  240.     NavTypeListHandle h = (NavTypeListHandle) NewHandleClear ( sizeof (NavTypeList) + 
  241.                                                                 (sizeof (OSType) * (numTypes-1)) );
  242.     if ( h != nil )
  243.     {
  244.         (*h)->componentSignature = (applSignature == 0L) ? 
  245.                                     StNavGetFile::GetApplSignature ( ) : applSignature;
  246.         (*h)->reserved = 0;
  247.         (*h)->osTypeCount = numTypes;
  248.         for ( int i = 0; i < numTypes; i++ )
  249.         {
  250.             OSType theType = va_arg ( argptrs, OSType );
  251.             (*h)->osType[i] = theType;
  252.         }
  253.     }
  254.     va_end ( argptrs );
  255.     return h;
  256. }
  257.  
  258. void StNavGetFile::GetFSSpecFromAEDesc ( AEDesc &inDesc, FSSpec &outValue )
  259. {
  260.     Handle    dataH;
  261.     AEDesc    coerceDesc = {typeNull, nil};
  262.  
  263.     if (inDesc.descriptorType == typeFSS) {
  264.         dataH = inDesc.dataHandle;        // Descriptor is the type we want
  265.         
  266.     } else {                            // Try to coerce to the desired type
  267.         if (::AECoerceDesc(&inDesc, typeFSS, &coerceDesc) == noErr) {
  268.                                         // Coercion succeeded
  269.             dataH = coerceDesc.dataHandle;
  270.  
  271.         } else {                        // Coercion failed
  272.             throw (errAETypeError);
  273.         }
  274.     }
  275.     
  276.     outValue = **(FSSpec**) dataH;    // Extract value from Handle
  277.     if (coerceDesc.dataHandle != nil) {
  278.         ::AEDisposeDesc(&coerceDesc);
  279.     }
  280. }
  281.  
  282. OSErr StNavGetFile::Init ( )
  283. {
  284.     if ( !NavServicesCanRun ( ) )
  285.         return kNavInvalidSystemConfigErr;
  286.         
  287.     return noErr;
  288. }
  289.